/**
 * Created by PengPeng on 2017/4/26.
 */
"use strict";

const moment = require("moment");
const pathToRegexp = require("path-to-regexp");

function factory(app, opts) {
  async function sendToKafkaAsync(producer, payloads) {
    return new Promise((resolve, reject) => {
      producer.send(payloads, function (err) {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  }

  async function logger(ctx, next) {
    const { path, method } = ctx;
    
    const start = Date.now();

    // 等待路由处理
    await next();

    try {
      let logAttr = null;
      let path_pattern = null;
      for (let prop in app.fs.api.logAttr) {
        let keys = [];
        let re = pathToRegexp(
          prop.replace(/\:[A-Za-z_\-]+\b/g, "(.*)").replace(/^\/|\/$/g, ""),
          keys
        );
        if (re.test(`${method}${path}`)) {
          logAttr = app.fs.api.logAttr[prop];
          path_pattern = prop.substring(prop.indexOf("/"));
          break;
        }
      }
      let parameter = null,
        parameterShow = null,
        user_id,
        _token,
        app_key;
      if (ctx.fs.api) {
        const { actionParameter, actionParameterShow, userId, token, appKey } =
          ctx.fs.api;
        parameter = actionParameter;
        parameterShow = actionParameterShow;
        user_id = userId;
        _token = token;
        app_key = appKey;
      }
      const producer = app.fs.kafka.producer;
      const message = {
        system: "运维服务平台",
        method: method,
        url: ctx.request.url,
        path_pattern: path_pattern,
        status_code: ctx.status,
        content: logAttr ? logAttr.content : "",
        ip: ctx.request.headers["x-real-ip"] || ctx.ip,
        agent: ctx.request.headers["user-agent"],
        user_id: user_id,
        username: (ctx.fs.api || {}).userName,
        log_time: moment().format("YYYY-MM-DD HH:mm:ss.SSS"),
      };

      const payloads = [
        {
          topic: `system_api_used`,
          messages: [JSON.stringify(message)],
          partition: 0,
        },
      ];

      await sendToKafkaAsync(producer, payloads);
    } catch (e) {
      ctx.fs.logger.error(`日志记录失败: ${e}`);
    }
  }
  return logger;
}

module.exports = factory;
